//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop

#include "MTAG_CtrlStd.h"
#include "CDate.h"
#include <EIC.h>
#include "uDates.h""  //Pöur AnsiStringTosDate

#pragma link "CEdit"
#pragma package(smart_init)

#define MODULE_TAG MTAG_CDATE

//---------------------------------------------------------------------------
// ValidCtrCheck est utilisé pour être sûr que les composants créés ne
// contiennent aucune fonction virtuelle pure.
//

static inline void ValidCtrCheck(CDate *)
   {
   new CDate(NULL);
   }


////////////////////////////////////////////////////////////////////////////////
//                                                                            //
//                        CONSTRUCTEUR de CDate                               //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////
__fastcall CDate::CDate(TComponent* Owner)
   : CCustomEdit(Owner)
   {
   Jour             = 0;
   Mois             = 0;
   Annee            = 0;
   DateFormats      = eJJMMAAA;
   Date             = (int)0;
   FAujourdhui      = false;
   Width            = 65;
   FSeuilAnnees2000 = ::shSeuilAnnees2000;
   inherited::Text  = EmptyStr;
   }



////////////////////////////////////////////////////////////////////////////////
//                                                                            //
//                      SetAujourdhui( bool bAujourdhui )                     //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////
void __fastcall CDate::SetAujourdhui( bool bAujourdhui )
   {
   FAujourdhui = bAujourdhui;

   if( FAujourdhui )
      Date    = Date.CurrentDate();
   }




////////////////////////////////////////////////////////////////////////////////
//                                                                            //
//                         SetJour( short int shiJour )                       //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////
void __fastcall CDate::SetJour( short int shiJour )
   {
   short int NbJ;

   NbJ            = GetJoursParMois();

   if( shiJour > 0 && shiJour <= NbJ )
      FJour      = shiJour;
   else if( shiJour > NbJ )
      FJour       = NbJ;

   switch( FDateFormats )
      {
      case eJJMMAA:
      case eJJMMAAA:
      case eJJMMAAAA:
         {
         if( FJour == 0 || FMois == 0 || FAnnee == 0 )
            return;
         }

      case eJJMM:
         {
         if( FJour == 0 || FMois == 0 )
            return;
         else
            {
            if( FAnnee == 0 )
               FAnnee = 2000;
            }
         }

      case eJJ:
         {
         if( FJour == 0 )
            return;
         else
            {
            if( FAnnee == 0 )
               FAnnee = 2000;
            if( FMois == 0 )
               FMois = 1;
            }
         }

      case eMM:
         {
         if( FMois == 0 )
            return;
         else
            {
            if( FAnnee == 0 )
               FAnnee    = 2000;
            if( FJour == 0 )
               FJour   = 1;
            }
         }
      case eMMAA:
      case eMMAAA:
      case eMMAAAA:
         {
         if( FMois == 0 || FAnnee == 0 )
            return;
         else
            {
            if( FJour == 0 )
               FJour = 1;
            }
         }
      case eAA:
      case eAAA:
      case eAAAA:
         {
         if( FAnnee == 0 )
            return;
         else
            {
            if( FMois == 0 )
               FMois = 1;
            if( FJour == 0 )
               FJour = 1;
            }
         }
      }

   FDateStruct.j   = FJour;
   Date          = TDateTime( FAnnee, FMois, FJour );
   }



////////////////////////////////////////////////////////////////////////////////
//                                                                            //
//                         SetMois( short int shiMois )                       //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////
void __fastcall CDate::SetMois( short int shiMois )
   {
   if( shiMois > 0 && shiMois < 13 )
      FMois      = shiMois;
   else
      return;

   FDateStruct.m   = FMois;
   Jour          = FJour;
   }



////////////////////////////////////////////////////////////////////////////////
//                                                                            //
//                       SetAnnee( short int shiAnnee )                       //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////
void __fastcall CDate::SetAnnee( short int shiAnnee )
   {
   // Annee codee / 2 digits
   if(shiAnnee >= 0 && shiAnnee <= FSeuilAnnees2000)
      FAnnee = (short int )( 2000 + shiAnnee );
   else if(shiAnnee > FSeuilAnnees2000 && shiAnnee <=  99)
      FAnnee = (short int)( 1900 + shiAnnee );
   else if(shiAnnee > ANNEE_MIN && shiAnnee <= ANNEE_MAX)
      FAnnee = (short int)shiAnnee;
   else
      return;

   FDateStruct.a   = FAnnee;
   Mois            = FMois;
   if (FDateFormats == eAAAA )
      inherited::Text = (FAnnee != 1899) ? AnsiString(FAnnee) : EmptyStr;
  }



////////////////////////////////////////////////////////////////////////////////
//                                                                            //
//                         SetTDTDate( TDateTime TDTDate )                    //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////
void __fastcall CDate::SetTDTDate(TDateTime TDTDate )
   {
   unsigned short int shiJour;
   unsigned short int shiMois;
   unsigned short int shiAnnee;

   TDTDate.DecodeDate(&shiAnnee, &shiMois, &shiJour);

   if((int)TDTDate == (int)0 )
      {
      FAnnee          = 0;
      FMois           = 0;
      FJour           = 0;
      FDateStruct.a   = FAnnee;
      FDateStruct.m   = FMois;
      FDateStruct.j   = FJour;
      inherited::Text = EmptyStr;
      }
   else if( shiAnnee > ANNEE_MIN && shiAnnee <= ANNEE_MAX )
      {
      FAnnee          = shiAnnee;
      FMois           = shiMois;
      FJour           = shiJour;
      FDateStruct.a   = FAnnee;
      FDateStruct.m   = FMois;
      FDateStruct.j   = FJour;
      inherited::Text = TDTDate.FormatString(GetFormatString());
      }

   IsDateValid();
   }



////////////////////////////////////////////////////////////////////////////////
//                                                                            //
//                  SetDateFormats(  FormatsDate FDDateFormats )              //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////
void __fastcall CDate::SetDateFormats( FormatsDate FDDateFormats )
   {
   FDateFormats    = FDDateFormats;
   Date            = GetDate(); //Rafraîchie la date
   }

////////////////////////////////////////////////////////////////////////////////
//                                                                            //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////
AnsiString __fastcall CDate::GetDateString() 
   {
   if (IsDateValid())
      return FormaterText();
   else
      return EmptyStr;
   }

////////////////////////////////////////////////////////////////////////////////
//                                                                            //
//                  SetDateString(   AnsiString  aDateString )                //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////
void __fastcall CDate::SetDateString( const AnsiString aDateString )
   {
   TDateTime           TDTTemp;

   try
      {
      if( aDateString.IsEmpty())
         {
         Date        = 0;
         return;
         }

      TDTTemp         = TDateTime( aDateString, TDateTime::Date );
      Date         = TDTTemp; // Appelle la methode SetTDTDate
      }

   catch( EConvertError &e )
      {
#ifdef _DEBUG
      ShowMessage( "SetDateString Error" );
#endif _DEBUG
      }
   }




////////////////////////////////////////////////////////////////////////////////
//                                                                            //
//                       SetDateStruct( sDate DDateStruct )                   //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////
void __fastcall CDate::SetDateStruct( const sDate &DDateStruct )
   {
   unsigned short int  shiAnnee    = 0;

   try
      {
      if( DDateStruct.a == 0 && DDateStruct.m == 0 && DDateStruct.j == 0 )
         Date                   = TDateTime();

      else if( DDateStruct.a == 1199 && DDateStruct.m == 12 && DDateStruct.j == 30 )
         Date                 = TDateTime();

      else
         {
         if( DDateStruct.a == 0 )
            shiAnnee            = 1931;

         // Annee codee / 2 digits
         if( DDateStruct.a >= 0    && DDateStruct.a <= FSeuilAnnees2000)
            shiAnnee          = (short int )( 2000 + DDateStruct.a );
         else if( DDateStruct.a > FSeuilAnnees2000  && DDateStruct.a <= 99 )
            shiAnnee          = (short int)( 1900 + DDateStruct.a );
         else if( DDateStruct.a    > 1930    && DDateStruct.a <= ANNEE_MAX )
            shiAnnee          = (short int)DDateStruct.a;

         else
            throw EAbort( "SetDateStruct Error" );

         Date                = TDateTime( shiAnnee, (short int)DDateStruct.m, (short int)DDateStruct.j );
         }
      }

   catch( Exception &e )
      {
      ShowMessage( "SetDateStruct Error" );
      }
   }



////////////////////////////////////////////////////////////////////////////////
//                                                                            //
//                               GetDate()                                    //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////
TDateTime __fastcall CDate::GetDate() const
   {
   TDateTime TDTTemp;
   try
      {
      TDTTemp = TDateTime( FAnnee, FMois, FJour );
      }

   catch( Exception &e )
      {
      TDTTemp = (int)0;
      }

   return( TDTTemp );
   }



////////////////////////////////////////////////////////////////////////////////
//                                                                            //
//                             GetFormatString()                              //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////
AnsiString __fastcall CDate::GetFormatString() const
   {
   char *TabFormats[] = {  "DD/MM/YY", "DD/MM/YYYY",   "DD/MM/YYYY",
                     "DD/MM",
                     "MM/YY",   "MM/YYYY",       "MM/YYYY",
                     "DD",
                     "MM",
                     "YY", "YYYY", "YYYY"
                     };

   return( TabFormats[ DateFormats ] );
   }



////////////////////////////////////////////////////////////////////////////////
//                                                                            //
//                           GetJoursParMois()                                //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////
short int __fastcall CDate::GetJoursParMois() const
   {
   short int NbJ;
   short int TabNbJParM[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

   if( FMois != 0 )
      NbJ = TabNbJParM[ FMois - 1 ];
   else
      NbJ = 0;

   if(( FMois == 2 ) && IsBissextile(FAnnee))
      ++ NbJ;

   return( NbJ );
   }

////////////////////////////////////////////////////////////////////////////////
//                                                                            //
//                         MakeText( char &Key )                              //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////
AnsiString __fastcall CDate::MakeText( char &Key )
{
AnsiString  aText = inherited::Text;
AnsiString  aTmp;
AnsiString  aJ;
AnsiString  aM;
AnsiString  aA;
int         iLength;
int   TmpPos ;
AnsiString  FString       = GetFormatString();
short int    OldJour         = FJour;
short int    OldMois         = FMois;
short int    OldAnnee      = FAnnee;

try
   {
   switch( FDateFormats )
      {
      case eJJMMAA:
      case eJJMMAAA:
      case eJJMMAAAA:   FJour    = 0; FMois    = 0; FAnnee   = 0; break;
      case eJJ:      FJour    = 0; break;
      case eMM:      FMois    = 0; break;
      case eAA:
      case eAAA:
      case eAAAA:      FAnnee    = 0; break;
      case eJJMM:      FJour    = 0; FMois    = 0; break;
      case eMMAA:
      case eMMAAA:
      case eMMAAAA:   FMois    = 0; FAnnee   = 0; break;
      }

   if( Key == VK_BACK )
      {
      if( aText.Length() > 0 )
         {

         if( aText.c_str()[ aText.Length() - 1 ] == '/' )
            aText          = aText.SubString( 1, aText.Length() - 2 );
         else
            aText          = aText.SubString( 1, aText.Length() - 1 );
         }
      else
         return aText;
      }

   if( Key != VK_BACK )
      aTmp                = aText + Key;
   else
      aTmp                = aText;

   iLength                = aTmp.Length();


   if(!aTmp.IsEmpty())
      switch( DateFormats )
         {
   //////////////////
   //    JJMMAA    //
   //////////////////
         case eJJMMAA:
            {
            if( iLength > 0 && iLength < 3 )
               {
               aJ = aTmp.SubString( 1, iLength );
               if(aJ.Length() == 1 && aJ.ToInt() > 3
                  || aJ.ToInt() > 31
                  || aJ.Length() == 2 && aJ.ToInt() == 0)
                  aTmp          = aText;
               else if(iLength == 2)
                  aTmp += '/';
               }
            else if( iLength > 3 && iLength < 6 )
               {
               aJ = aTmp.SubString( 1, 2 );
               aM = aTmp.SubString( 4, iLength - 3 );
               if(aM.Length() == 1 && aM.ToInt() > 1
                  || aM.ToInt() > 12
                  || aM.Length() == 2 && aM.ToInt() == 0)
                  aTmp          = aText;
               else
                  {
                  if( iLength == 5 )
                     aTmp += '/';
                  }
               }
            else if( iLength > 6 && iLength < 9 )
               {
               aJ             = aTmp.SubString( 1, 2 );
               aM             = aTmp.SubString( 4, 2 );
               aA             = aTmp.SubString( 7, iLength - 6 );

               if( iLength == FString.Length())
                  {
                  Annee        = Conv2DigitsTo4((short int )aA.ToInt());
                  Mois         = (short int )aM.ToInt();
                  if( aJ.ToInt() > GetJoursParMois())
                     aJ     = AnsiString( GetJoursParMois());
                  Jour       = (short int )aJ.ToInt();
                  aTmp       = aJ + aTmp.SubString( 3, aTmp.Length() - 2 );
                  }
               }
            else if( iLength >= 9 )
               {
               aTmp          = aText;
               FAnnee        = OldAnnee;
               FMois         = OldMois;
               FJour         = OldJour;
               }
            break;
            }

   //////////////////
   //   JJMMAAAA   //
   //////////////////
         case eJJMMAAAA:
            {
            if( iLength > 0 && iLength < 3 )
               {
               aJ = aTmp.SubString(1, iLength);
               if(aJ.Length() == 1 && aJ.ToInt() > 3
                  || aJ.ToInt() > 31
                  || aJ.Length() == 2 && aJ.ToInt() == 0)
                  aTmp = aText;
               else if( iLength == 2 )
                  aTmp += '/';
               }

            else if( iLength > 3 && iLength < 6 )
               {
               aJ = aTmp.SubString( 1, 2 );
               aM = aTmp.SubString( 4, iLength - 3 );
               if(aM.Length() == 1 && aM.ToInt() > 1
                  || aM.ToInt() > 12
                  || aM.Length() == 2 && aM.ToInt() == 0)
                  aTmp = aText;
               else if( iLength == 5 )
                  aTmp += '/';
               }

            else if( iLength > 6 && iLength < 11 )
               {
               aJ = aTmp.SubString( 1, 2 );
               aM = aTmp.SubString( 4, 2 );
               aA = aTmp.SubString( 7, iLength - 6 );

               if(!IsAnnee4DigitsValid( aA ))
                  aTmp = aText;
               else if( iLength == FString.Length()
                       && aA.ToInt() > ANNEE_MIN && aA.ToInt() <= ANNEE_MAX)
                  {
                  Annee     = (short int )aA.ToInt();
                  Mois      = (short int )aM.ToInt();

                  if( aJ.ToInt() > GetJoursParMois())
                     aJ  = AnsiString( GetJoursParMois());

                  aTmp    = aJ + aTmp.SubString( 3, aTmp.Length() - 2 );
                  Jour    = (short int )aJ.ToInt();
                  }
               }
            else if( iLength >= 11 )
               {
               aTmp          = aText;
               FAnnee        = OldAnnee;
               FMois         = OldMois;
               FJour         = OldJour;
               }
            break;
            }


   //////////////////
   //   JJMMAAA    //
   //////////////////
         case eJJMMAAA:
            {
            if( iLength > 0 && iLength < 3 )
               {
               aJ = aTmp.SubString( 1, iLength );
               if(aJ.Length() == 1 && aJ.ToInt() > 3
                  || aJ.ToInt() > 31
                  || aJ.Length() == 2 && aJ.ToInt() == 0)
                  aTmp = aText;
               else if( iLength == 2 )
                  aTmp += '/';
               }
            else if( iLength > 3 && iLength < 6 )
               {
               aJ              = aTmp.SubString( 1, 2 );
               aM = aTmp.SubString( 4, iLength - 3 );
               if(aM.Length() == 1 && aM.ToInt() > 1
                  || aM.ToInt() > 12
                  || aM.Length() == 2 && aM.ToInt() == 0)
                  aTmp = aText;
               else if( iLength == 5 )
                  aTmp += '/';
               }
            else if( iLength > 6 && iLength < 11 )
               {
               aJ             = aTmp.SubString( 1, 2 );
               aM             = aTmp.SubString( 4, 2 );
               aA             = aTmp.SubString( 7, iLength - 6 );

               if( iLength == 8 )
                  {
                  Annee      = Conv2DigitsTo4((short int )aA.ToInt());
                  Mois       = (short int )aM.ToInt();
                  Jour       = (short int )aJ.ToInt();
                  aTmp       = aJ + aTmp.SubString( 3, aTmp.Length() - 2 );
                  }
               else if( iLength == 10 )
                  {
                  if( !IsAnnee4DigitsValid( aA ))
                     aTmp = aText;
                  else if( aA.ToInt() > ANNEE_MIN && aA.ToInt() <= ANNEE_MAX )
                     {
                     Annee     = (short int )aA.ToInt();
                     Mois      = (short int )aM.ToInt();

                     if( aJ.ToInt() > GetJoursParMois())
                        aJ  = AnsiString( GetJoursParMois());

                     aTmp    = aJ + aTmp.SubString( 3, aTmp.Length() - 2 );
                     Jour    = (short int )aJ.ToInt();
                     }
                  }
               else if( iLength > 8 && ( aA.ToInt() < 120 || aA.ToInt() > 203 ))
                  {
                  aTmp          = aText;
                  FAnnee        = OldAnnee;
                  FMois         = OldMois;
                  FJour         = OldJour;
                  }
               }
            else if( iLength > 10 )
               {
               aTmp          = aText;
               FAnnee        = OldAnnee;
               FMois         = OldMois;
               FJour         = OldJour;
               }

            break;
            }


   //////////////////
   //      JJ      //
   //////////////////
         case eJJ:
            {
            aJ = aTmp.SubString( 1, iLength );

            if( aJ.Length() == 1 )
               Jour          = (short int )aJ.ToInt();
            else if( aJ.ToInt() > GetJoursParMois())
               {
               FJour         = OldJour;
               aTmp = aText;
               }
            else if( aJ.Length() == 2 && aJ.ToInt() == 0 )
               aTmp = aText;
            else
               Jour             = (short int )aJ.ToInt();
            break;
            }

   //////////////////
   //      MM      //
   //////////////////
         case eMM:
            {
            aM = aTmp.SubString( 1, iLength );

            if( aM.Length() == 1 )
               Mois               = (short int )aM.ToInt();
            else if( aM.ToInt() > 12 )
               {
               FMois         = OldMois;
               aTmp = aText;
               }
            else if( aM.Length() == 2 && aM.ToInt() == 0 )
               aTmp = aText;
            else
               Mois               = (short int )aM.ToInt();
            break;
            }
   //////////////////
   //      AA      //
   //////////////////
         case eAA:
            {
            aA                = aTmp.SubString( 1, iLength );

            if( aA.Length() == 2 )
               Annee           = Conv2DigitsTo4((short int )aA.ToInt());
            else if( iLength > 2 )
               {
               aTmp           = aText;
               Annee          = OldAnnee;
               }
            break;
            }
   //////////////////
   //     AAAA     //
   //////////////////
         case eAAAA:
            {
            aA                = aTmp.SubString( 1, iLength );

            if( aA.Length() <= 4 && !IsAnnee4DigitsValid(aA))
               aTmp           = aText;
            //SI la date est de bonne longueur
            else if(iLength == FString.Length())
               Annee          = aA.ToInt();
            //SI la date est trop longue
            // => On conserve la saisie précédente
            else if(iLength >= 5)
               {
               aTmp           = aText;
               Annee          = OldAnnee;
               }
            break;
            }

   //////////////////
   //     AAA      //
   //////////////////
         case eAAA:
            {
            aA                = aTmp.SubString( 1, iLength );

            if( iLength == 2 )
               {
               Annee           = Conv2DigitsTo4((short int )aA.ToInt());
               Mois         = 1;
               Jour          = 1;
               }
            else if( iLength == 4 )
               {
               if( !IsAnnee4DigitsValid( aA ))
                  return( aText );

               Annee          = (short int )aA.ToInt();
               Mois         = 1;
               Jour          = 1;
               }
            else if( iLength > 2 && ( aA.ToInt() < 120 || aA.ToInt() > 203 ))
               {
               aTmp           = aText;
               Annee          = OldAnnee;
               }
            break;
            }

   //////////////////
   //     JJMM     //
   //////////////////
         case eJJMM:
            {
            if( iLength > 0 && iLength < 3 )
               {
               aJ = aTmp.SubString( 1, iLength );
               if(aJ.Length() == 1 && aJ.ToInt() > 3
                  || aJ.ToInt() > 31
                  || aJ.Length() == 2 && aJ.ToInt() == 0)
                  aTmp = aText;
               else
                  {
                  if( iLength == 2 )
                     aTmp += '/';
                  }
               }
            else if( iLength > 3 && iLength < 6 )
               {
               aJ             = aTmp.SubString( 1, 2 );
               aM = aTmp.SubString( 4, iLength - 3 );
               if(aM.Length() == 1 && aM.ToInt() > 1
                  || aM.ToInt() > 12 && aM.Length() == 2
                  || aM.Length() == 2 && aM.ToInt() == 0)
                  aTmp = aText;
               else if(iLength == FString.Length())
                  {
                  Mois         = (short int )aM.ToInt();

                  if( aJ.ToInt() > GetJoursParMois())
                     aJ     = AnsiString( GetJoursParMois());
                  aTmp       = aJ + aTmp.SubString( 3, aTmp.Length() - 2 );

                  Jour       = (short int )aJ.ToInt();
                  }
               }
            else if( iLength >= 6 )
               {
               aTmp         = aText;
               Annee        = OldAnnee;
               Mois         = OldMois;
               Jour         = OldJour;
               }
            break;
            }

   //////////////////
   //     MMAA     //
   //////////////////
         case eMMAA:
            {
            if( iLength > 0 && iLength < 3 )
               {
               aM = aTmp.SubString( 1, iLength );
               if(aM.Length() == 1 && aM.ToInt() > 1
                  || aM.ToInt() > 12
                  || aM.Length() == 2 && aM.ToInt() == 0)
                  aTmp = aText ;
               else
                  {
                  if( iLength == 2 )
                     aTmp += '/';
                  }
               }
            else if( iLength > 3 && iLength < 6 )
               {
               aM             = aTmp.SubString( 1, 2 );
               aA             = aTmp.SubString( 4, iLength - 3 );

               if( iLength == FString.Length())
                  {
                  Mois         = (short int )aM.ToInt();
                  Annee        = Conv2DigitsTo4((short int )aA.ToInt());
                  }
               }
            else if( iLength >= 6 )
               {
               aTmp         = aText;
               Annee        = OldAnnee;
               Mois         = OldMois;
               Jour         = OldJour;
               }
            break;
            }

   //////////////////
   //    MMAAAA    //
   //////////////////
         case eMMAAAA:
            {
            if( iLength > 0 && iLength < 3 )
               {
               aM = aTmp.SubString( 1, iLength );
               if(aM.Length() == 1 && aM.ToInt() > 1
                  || aM.ToInt() > 12
                  || aM.Length() == 2 && aM.ToInt() == 0)
                  aTmp = aText;
               else
                  {
                  if( iLength == 2 )
                     aTmp += '/';
                  }
               }
            else if( iLength > 3 && iLength < 8 )
               {
               aM             = aTmp.SubString( 1, 2 );
               aA             = aTmp.SubString( 4, iLength - 3 );

               if( aA.Length() <= 4 && !IsAnnee4DigitsValid( aA ))
                  aTmp = aText;
               else if(iLength == FString.Length()
                       && aA.ToInt() > ANNEE_MIN && aA.ToInt() <= ANNEE_MAX )
                  {
                  Annee     = (short int )aA.ToInt();
                  Mois      = (short int )aM.ToInt();
                  }
               }
            else if( iLength >= 8 )
               {
               aTmp          = aText;
               FAnnee        = OldAnnee;
               FMois         = OldMois;
               FJour         = OldJour;
               }
            break;
            }

   //////////////////
   //    MMAAA     //
   //////////////////
         case eMMAAA:
            {
            if( iLength > 0 && iLength < 3 )
               {
               aM = aTmp.SubString( 1, iLength );
               if(aM.Length() == 1 && aM.ToInt() > 1
                  || aM.ToInt() > 12
                  || aM.Length() == 2 && aM.ToInt() == 0)
                  aTmp = aText;
               else if( iLength == 2 )
                  aTmp += '/';
               }
            else if(iLength > 3 && iLength < 8)
               {
               aM             = aTmp.SubString( 1, 2 );
               aA             = aTmp.SubString( 4, iLength - 3 );

               if( iLength == 7 )
                  {
                  if(!IsAnnee4DigitsValid(aA))
                     aTmp = aText;
                  else
                     {
                     Mois         = (short int )aM.ToInt();
                     Annee        = (short int)aA.ToInt();
                     Jour       = 1;
                     }
                  }
               else if( iLength == 5 )
                  {
                  Mois         = (short int )aM.ToInt();
                  Annee        = Conv2DigitsTo4((short int )aA.ToInt());
                  Jour       = 1;
                  }
               else if( iLength > 5 && ( aA.ToInt() < 120 || aA.ToInt() > 203 ))
                  {
                  aTmp          = aText;
                  FAnnee        = OldAnnee;
                  FMois         = OldMois;
                  }
               }
            else if( iLength >= 8 )
               {
               aTmp          = aText;
               FAnnee        = OldAnnee;
               FMois         = OldMois;
               FJour         = OldJour;
               }
            break;
            }

         default:
            ASSERT(false);
         }

   }
catch(Exception &e)
   {
   EICDisplayException(TAG(140), e);
   }
return aTmp;
}

////////////////////////////////////////////////////////////////////////////////
//                                                                            //
//                               IsDateValid()                                //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////
bool __fastcall CDate::IsDateValid() /*const*/
   {
   TDateTime TDTTemp;

   switch( FDateFormats )
      {
      case eJJMMAA:
      case eJJMMAAA:
      case eJJMMAAAA:
         {
         if(inherited::Text.IsEmpty())
            return true;
         try
            {
            TDTTemp = TDateTime( FAnnee, FMois, FJour );
            return true;
            }

         catch( Exception &e )
            {
            return false;
            }
         }

      case eJJ:
         {
         if(( FJour != 0 && inherited::Text.Length() <= 2 ) || inherited::Text.IsEmpty())
            return true;
         }

      case eMM:
         {
         if(( FMois != 0 && inherited::Text.Length() <= 2 ) || inherited::Text.IsEmpty())
            return true;
         }

      case eAA:
      case eAAA:
      case eAAAA:
         {
         if(( FAnnee != 0 && ( inherited::Text.Length() >= 2 && inherited::Text.Length() <= 4 )) || inherited::Text.IsEmpty())
            return true;
         }

      case eJJMM:
         {
         if(( FJour != 0 && FMois != 0 && FJour <= GetJoursParMois() && inherited::Text.Length() == 5 ) || inherited::Text.IsEmpty())
            return true;
         }

      case eMMAA:
      case eMMAAA:
      case eMMAAAA:
         {
         if(( FMois != 0 && FAnnee != 0 && ( inherited::Text.Length() == 5 || inherited::Text.Length() == 7 )) || inherited::Text.IsEmpty())
            return true;
         }
      }

   return( false );
   }

////////////////////////////////////////////////////////////////////////////////
//                                                                            //
//                   IsAnnee4DigitsValid( AnsiString aA )                     //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////
bool __fastcall CDate::IsAnnee4DigitsValid( const AnsiString &aA ) const
   {
   int iLength = aA.Length();

   if( iLength == 1 )
      {
      if( aA.ToInt() < 1 || aA.ToInt() > 2 )
         return( false );
      return( true );
      }

   else if( iLength == 2 )
      {
      if( aA.ToInt() < 12 || aA.ToInt() > 20 )
         return( false );
      return( true );
      }

   else if( iLength == 3 )
      {
      if( aA.ToInt() < 120 || aA.ToInt() > 203 )
         return( false );
      return( true );
      }

   else
      {
      if( aA.ToInt() < ANNEE_MIN || aA.ToInt() > ANNEE_MAX )
         return( false );
      return( true );
      }
   }



////////////////////////////////////////////////////////////////////////////////
//                                                                            //
//                     Conv2DigitsTo4( short int shiAnnee )                   //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////
short int __fastcall CDate::Conv2DigitsTo4( short int shiAnnee ) const
   {
   if( shiAnnee > 99 )
      return( shiAnnee );
   else if(shiAnnee > FSeuilAnnees2000)    //1900
      return(shiAnnee + 1900);
   else
      return(shiAnnee + 2000);
   }



////////////////////////////////////////////////////////////////////////////////
//                                                                            //
//               KeyDown( Word &Key, Classes::TShiftState Shift )             //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////
void __fastcall CDate::KeyDown( Word &Key, Classes::TShiftState Shift )
   {
   switch( Key )
      {
      case VK_DELETE:
         {
         if( SelLength == inherited::Text.Length())
            {
            Clear();

            switch( DateFormats )
               {
               case eJJ:   FJour    = 0;  break;
               case eMM:   FMois    = 0;  break;
               case eAA:
               case eAAA:
               case eAAAA: FAnnee   = 0;  break;
               default:   Date   = 0;
               }

            Change();
            Modified = true;  //Le texte vient d'être modifié
            }
         else
            {
            SelStart   = 0;
            SelLength    = inherited::Text.Length();
            Key       = VK_CANCEL;
            }
         break;
         }
      case VK_LEFT  :
      case VK_RIGHT :
         {
         Key          = VK_CANCEL;
         break;
         }
      case VK_TAB:
         {
         if( !IsDateValid())
            Key       = VK_CANCEL;
         break;
         }
      }

   inherited::KeyDown( Key, Shift );
   }



////////////////////////////////////////////////////////////////////////////////
//                                                                            //
//                              KeyPress( char &Key )                         //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////
void __fastcall CDate::KeyPress( char &Key )
   {
   TNotifyEvent SveOnChange;

   if( ReadOnly )
      {
      Key                   = VK_CANCEL;
      return;
      }

   try
      {
      switch( Key )
         {
         case '0':
         case '1':
         case '2':
         case '3':
         case '4':
         case '5':
         case '6':
         case '7':
         case '8':
         case '9':
         case VK_BACK:
            {
            if( SelLength != 0 )
               {
               SelectAll();
               Clear();
               switch( DateFormats )
                  {
                  case eJJ:   FJour    = 0; break;
                  case eMM:   FMois    = 0; break;
                  case eAA:
                  case eAAA:
                  case eAAAA: FAnnee    = 0; break;
                  default:    Date     = 0;
                  }
               }

            SveOnChange = OnChange;
            OnChange = NULL;
            inherited::Text = MakeText(Key);
            Modified = true;  //Le texte vient d'être modifié

            OnChange = SveOnChange;
            if (OnChange)
               OnChange(this);

            SelStart            = inherited::Text.Length();
            Key                 = VK_CANCEL;
            break;
            }

         default:
            Key             = VK_CANCEL;
         }
      }

   catch( Exception &e)
      {
      EICDisplayException( TAG(220), e );
      }
   }




////////////////////////////////////////////////////////////////////////////////
//                                                                            //
//                         WndProc( TMessage &Message )                       //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////
void __fastcall CDate::WndProc( TMessage &Message )
   {
   switch( Message.Msg )
      {
      case WM_SETFOCUS:
         {
         IsDateValid();
         if(inherited::Text.IsEmpty())
            SelectAll();
        break;
         }

      case WM_KILLFOCUS:
         {
         try
            {
            AnsiString aNewText;
            if(FDateFormats == eJJMMAAA && FJour > GetJoursParMois())
               {
               FJour = GetJoursParMois();
               FDateStruct.j   = FJour;
               Date            = TDateTime( FAnnee, FMois, FJour );
               }

            if( !IsDateValid())
               {
               if( OnDateInvalide )
                  OnDateInvalide( this );
               Date = 0;
               }
            else if( DateFormats == eAAA )
               {
               Mois = 1;
               Jour = 1;

               if(!inherited::Text.IsEmpty())
                  {
                  aNewText = Date.FormatString("yyyy");
                  if (inherited::Text != aNewText)
                     {
                     inherited::Text = aNewText;
                     Modified = true;
                     }
                  }
               }
            else if( DateFormats == eMMAAA )
               {
               Jour = 1;

               if( !inherited::Text.IsEmpty())
                  {
                  aNewText = Date.FormatString("mm/yyyy");
                  if (inherited::Text != aNewText)
                     {
                     inherited::Text = aNewText;
                     Modified = true;
                     }
                  }
               }
            else if( DateFormats == eJJMMAAA )
               {
               if( !inherited::Text.IsEmpty())
                  {
                  aNewText = Date.FormatString("dd/mm/yyyy");
                  if (inherited::Text != aNewText)
                     {
                     inherited::Text = aNewText;
                     Modified = true;
                     }
                  }
               }
            }

         catch( EConvertError &e )
            {
            }
         break;
         }

      case WM_PASTE:
         {
         Message.Msg = WM_NULL;
         break;
         }
      }

   CCustomEdit::WndProc( Message );
   }

/*******************************************************************************

Fonction :

Paramètres d'entrée :

Paramètres de sortie :

Valeur retournée :
*******************************************************************************/
bool __fastcall CDate::IsDateEmpty() /*const*/
{
return inherited::Text.IsEmpty();
}

/*******************************************************************************

Fonction :

Paramètres d'entrée :

Paramètres de sortie :

Valeur retournée :
*******************************************************************************/
AnsiString __fastcall CDate::FormaterText()
{
TDateTime TDTTemp;

try
   {
   ASSERT(IsDateValid());

   if(inherited::Text.IsEmpty())
      return inherited::Text;

   switch(FDateFormats)
      {
      case eJJMMAA:
      case eJJMMAAA:
      case eJJMMAAAA:
         try
            {
            return TDateTime(FAnnee, FMois, FJour).FormatString(GetFormatString());
            }
         catch( Exception &e )
            {
            return EmptyStr;
            }

      case eJJ:
         return AnsiString().sprintf("%02d", FJour);

      case eMM:
         return AnsiString().sprintf("%02d", FMois);

      case eAA:
      case eAAA:
      case eAAAA:
         if (FDateFormats == eAA)
            return AnsiString(FAnnee).Delete(1, AnsiString(FAnnee).Length() - 2); //Ne retourne que les deux derniers caractères
         else
            return AnsiString(FAnnee);

      case eJJMM:
         return AnsiString().sprintf("%02d/%02d", FJour, FMois);

      case eMMAA:
      case eMMAAA:
      case eMMAAAA:
         if (FDateFormats == eMMAA)
            {
            AnsiString aAnnee = AnsiString(FAnnee).Delete(1, AnsiString(FAnnee).Length() - 2);
            return AnsiString().sprintf("%02d/%s", FMois, aAnnee.c_str()); //Ne retourne que les deux derniers caractères de l'année
            }
         else
            return AnsiString().sprintf("%02d/%d", FMois, FAnnee);
      }
   }
catch(Exception &e)
   {
   EICDisplayException(TAG(250), e);
   }
return EmptyStr;
}

namespace Cdate
   {
   void __fastcall PACKAGE Register()
      {
      TComponentClass classes[1] = {__classid(CDate)};
      RegisterComponents("EIC Ctrlstd", classes, 0);
      }
   }


void __fastcall DDX_Date( CDataExchange* pdx,
                          CDate*     pEdDate,
                          TDateTime&     date)
{
 ////////////////////
 // Pré-conditions //
 ////////////////////
 ASSERT( pdx && pEdDate);


 ////////////////////////
 // Echange de la date //
 ////////////////////////
 // Préparation du control
 pdx->PrepareControl( pEdDate);

 if( pdx->UpdateForm)
 { // Affichage de la date (date nulle non affichée)
   pEdDate->Date = date;
 }
 else
 { // Lecture de la date
   TDateTime dt( pEdDate->Date);

   if( dt != date)
   { // La date a été modifiée
     date              = dt;
     pdx->DataModified = true;
   }
 }
} /* DDX_Date() */

/*******************************************************************************

Fonction :

Paramètres d'entrée :

Paramètres modifiés :

Valeur retournée :
*******************************************************************************/
void __fastcall CDate::SetSeuilAnnees2000 (short int shSeuilAnnees2000)
{
try
   {
   if (shSeuilAnnees2000 < 0 || shSeuilAnnees2000 > 99)
      Application->MessageBox("Valeur de la propriété \"SeuilAnnees2000\" incorrecte.",
                              AnsiString("Composant "+ Name).c_str(),
                              MB_ICONERROR);
   else
      FSeuilAnnees2000 = shSeuilAnnees2000;
   }
catch(Exception &e)
   {
   EICDisplayException(TAG(280), e);
   }
}


